use super::common::{MiddlewareRejectType, MiddlewareStruct, RequestStruct};

pub type Middleware = fn(RequestStruct) -> MiddlewareStruct;

/// Middleware works after the parser and before route matching
static mut MIDDLEWARES: Vec<Middleware> = Vec::new();


#[allow(dead_code)]
pub(crate) fn add_middleware(middleware: Middleware) {
    unsafe {
        MIDDLEWARES.push(middleware);
    }
}

#[allow(dead_code)]
pub(crate) fn call_middleware(request: RequestStruct) -> MiddlewareStruct {
    let mut result = MiddlewareStruct {
        request,
        reject_type: MiddlewareRejectType::None,
        reject_passage: false,
    };
    unsafe {
        for middleware in MIDDLEWARES.iter() {
            let res = middleware(result.request);
            result = res;
            if result.reject_passage {
                break;
            };
        }
    }
    result
}

#[allow(dead_code)]
pub(crate) fn get_middleware() -> Vec<Middleware> {
    unsafe { MIDDLEWARES.clone() }
}

#[allow(dead_code)]
pub(crate) fn get_middleware_item(index: usize) -> Option<Middleware> {
    unsafe { MIDDLEWARES.get(index).copied() }
}

#[allow(dead_code)]
pub(crate) fn clear_middleware() {
    unsafe {
        MIDDLEWARES.clear();
    }
}
